package island

import (
	"sync"
)

var overlayInfo *overlayMountInfo

func IslandCleanUp() {
	logger.Debug("clean up island")

	// 清理overlay mount
	logger.Info("clean up the overlay mount")
	overlayInfo.clean()

	db.Range(func(k, v interface{}) bool {
		item := v.(*dbItem)
		if item.container.State.String() == StatusRunning {
			// send SIGTERM to container
			if err := item.container.Kill("SIGTERM", true); err != nil {
				logger.WithField("id", item.container.ID).WithField("error", err).Error("get not stop this container")
			} else {
				logger.WithField("id", item.container.ID).Debug("stop this container successfully")
			}
		}
		return true
	})
}

func (ml *overlayMountInfo) register(id string) {
	ml.mountInfoLock.Lock()
	defer ml.mountInfoLock.Unlock()
	logger.WithField("id", id).Info("the container overlay mount registered")
	ml.mountMap[id] = 1
}

func (ml *overlayMountInfo) unRegister(id string) {
	ml.mountInfoLock.RLock()
	defer ml.mountInfoLock.RUnlock()
	if _, ok := ml.mountMap[id]; !ok {
		logger.WithField("id", id).Error("cannot unregister the container overlay did not register ")
	} else {
		logger.WithField("id", id).Info("unregister the container overlay mount")
		delete(ml.mountMap, id)
	}
}

func (ml *overlayMountInfo) clean() {
	ml.mountInfoLock.Lock()
	defer ml.mountInfoLock.Unlock()

	// 因为就算clean中某一个失败,也不应该返回,应该尽可能的清理
	for id, _ := range ml.mountMap {
		if err := overlayUnmount(id); err != nil {
			logger.WithField("id", id).Error(err)
		} else {
			logger.WithField("id", id).Info("unmount the overlay")
		}
	}
}

func newOverlayInfo() *overlayMountInfo {
	return &overlayMountInfo{
		mountMap:      make(map[string]int),
		mountInfoLock: sync.RWMutex{},
	}
}
